package com.appspot.mscheckers;

import java.io.IOException;
import java.util.Hashtable;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.appspot.mscheckers.core.Position;
import com.google.appengine.api.channel.ChannelMessage;
import com.google.appengine.api.channel.ChannelService;
import com.google.appengine.api.channel.ChannelServiceFactory;
import com.google.gson.Gson;

public class GameServlet extends HttpServlet{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	public static Hashtable<String, Game> gameMap = new Hashtable<String, Game>(20);
	
	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		resp.setContentType("text/plain");
		Gson gson = new Gson();
		String r="";
		
		if(req.getParameter(Constant.ACTION) == null ){
			resp.getWriter().print(r);
			return;
		}
		
		String action = req.getParameter(Constant.ACTION).toString();
		String userId;
		char piece;
		String rId;
		String tk;
		Game gm;
		ChannelService channelService ;
		Checkers.log.info("++++++++++++GameServlet+++++++++++++++ : "+action);
		switch(action){
			
			case Constant.GAME_MOVE:
				Checkers.log.info("++++++++++++GAME_MOVE++++++++++++");
				userId = req.getParameter(Constant.USER_ID).toString();
				tk = req.getParameter(Constant.GAME_TOKEN).toString();
				piece = req.getParameter(Constant.GAME_PIECE).toString().charAt(0);
				Position[] mtr = gson.fromJson(req.getParameter("mt[]").toString(), Position[].class);
				
				gm = gameMap.get(tk);  
				
				if( gm != null && gm.move(mtr, piece) == true){
					rId = gm.getUserId(userId);
					Checkers.log.info("++++++++++++GAME_MOVE    Sending Move to remote host id "+rId+"++++++++++++");
					channelService = ChannelServiceFactory.getChannelService();
					channelService.sendMessage(new ChannelMessage(rId, "{\""+Constant.MESSAGE_TYPE+"\":\""+Constant.GAME_MOVE+"\"}"));
				    channelService.sendMessage(new ChannelMessage(rId, gson.toJson(mtr)));		
				    
				    if( gm.getMTable() == null ){
					    channelService.sendMessage(new ChannelMessage(rId, "{\""+Constant.MESSAGE_TYPE+"\":\""+Constant.GAME_PLAY+"\"}"));
					    channelService.sendMessage(new ChannelMessage(rId, gson.toJson(Constant.GAME_PLAY)));					    	
				    }
				    
				}else
					Checkers.log.info("++++++++++++GAME_MOVE  game not "+gm+" OR invalid move for token "+tk+" AND mtr "+mtr+" ++++++++++++");
				
				break;	
			case Constant.GAME_MTABLE:
				userId = req.getParameter(Constant.USER_ID).toString();
				tk = req.getParameter(Constant.GAME_TOKEN).toString();
				piece = req.getParameter(Constant.GAME_PIECE).toString().charAt(0);
				gm = gameMap.get(tk) ;  
				
				if( gm != null ){
					Position[][] mt = gm.getMTable(piece);
					
					channelService = ChannelServiceFactory.getChannelService();
					channelService.sendMessage(new ChannelMessage(userId, "{\""+Constant.MESSAGE_TYPE+"\":\""+Constant.GAME_MTABLE+"\"}"));
				    channelService.sendMessage(new ChannelMessage(userId, gson.toJson(mt)));						
				}
				
				break;
			case Constant.JOIN_GAME :
				userId = req.getParameter(Constant.USER_ID).toString();
				tk = req.getParameter(Constant.GAME_TOKEN).toString();
				rId = Checkers.gameTokenList.get(tk);
				
				channelService = ChannelServiceFactory.getChannelService();
				if( rId != null && Checkers.userMap.get(rId) != null /*&& playerMap.get(rId) == null && playerMap.get(userId)== null */){  
					
					Checkers.gameTokenList.remove(tk);
					Checkers.playerMap.put(userId, Checkers.userMap.get(userId));
					Checkers.playerMap.put(rId, Checkers.userMap.get(rId));
					
					gm = new Game(userId, rId);
					gameMap.put(tk, gm);
					
					//----USER 1
					channelService.sendMessage(new ChannelMessage(userId, "{\""+Constant.MESSAGE_TYPE+"\":\""+Constant.JOIN_GAME+"\"}"));
				    channelService.sendMessage(new ChannelMessage(userId, gson.toJson(Checkers.userMap.get(rId))));						
					channelService.sendMessage(new ChannelMessage(userId, "{\""+Constant.MESSAGE_TYPE+"\":\""+Constant.GAME_BOARD+"\"}"));
				    channelService.sendMessage(new ChannelMessage(userId, gson.toJson(gm.getCBoard())));	
					channelService.sendMessage(new ChannelMessage(userId, "{\""+Constant.MESSAGE_TYPE+"\":\""+Constant.GAME_PIECE+"\"}"));
				    channelService.sendMessage(new ChannelMessage(userId, gson.toJson(gm.getTurn())));	
				    
				    channelService.sendMessage(new ChannelMessage(userId, "{\""+Constant.MESSAGE_TYPE+"\":\""+Constant.GAME_PLAY+"\"}"));
				    channelService.sendMessage(new ChannelMessage(userId, gson.toJson(Constant.GAME_PLAY)));	
				    
				    
				    //----USER 2
				    channelService.sendMessage(new ChannelMessage(rId, "{\""+Constant.MESSAGE_TYPE+"\":\""+Constant.JOIN_GAME+"\"}"));
				    channelService.sendMessage(new ChannelMessage(rId, gson.toJson(Checkers.userMap.get(userId))));	 
					channelService.sendMessage(new ChannelMessage(rId, "{\""+Constant.MESSAGE_TYPE+"\":\""+Constant.GAME_BOARD+"\"}"));
				    channelService.sendMessage(new ChannelMessage(rId, gson.toJson(gm.getCBoard())));	
					channelService.sendMessage(new ChannelMessage(rId, "{\""+Constant.MESSAGE_TYPE+"\":\""+Constant.GAME_PIECE+"\"}"));
				    channelService.sendMessage(new ChannelMessage(rId, gson.toJson(gm.getRTurn())));	
				}else{
				    channelService.sendMessage(new ChannelMessage(userId, "{\""+Constant.MESSAGE_TYPE+"\":\""+Constant.GAME_JOINING_FAILED+"\"}"));
				    channelService.sendMessage(new ChannelMessage(userId, gson.toJson(tk)));	
				}
				break;
		}
		resp.getWriter().print(r);
	}

}
